ホームに戻る
出典 :
Raiseメソッド (Visual Basic for Applications) | Microsoft Learn Office TANAKA - Excel VBA Tips[エラーに負けない] 【VBA入門】エラーを処理する方法(On Error、Resume、GoTo) | 侍エンジニアブログ vbaのエラー処理 - Qiita
関連 :
[C++]例外処理
目次 :

VBAにおけるエラー処理

VBAではエラーへの対処を On Error ステートメントを用いて記述することができる。
これはオブジェクト指向言語における例外処理に類似するが、本来の例外機構と比較して機能は限定されている。

エラー処理の意義


エラー処理を実装せずにプログラムを実行してエラーが発生した場合、
エラーはシステムによって捕捉され、上図のようなダイアログが表示されてプログラムの実行は停止される。
エラー処理を実装することで、発生したエラーをプログラムが主体的に捕捉、適切に処理したうえでプログラムの実行を継続させることができる。

エラー処理の類型


On Error ステートメントをプログラム中に記述すると、ステートメントの直後からプロシージャの末尾までの範囲内で発生したエラーを捕捉する。
(別の On Error ステートメントがプロシージャ中に存在しない場合)
エラーを捕捉した場合の処置は、主に以下の二つに大別される。

次行から継続 : On Error Resume Next

Sub Sample() ' エラー監視 ここから On Error Resume Next DoSomething1 DoSomething2 DoSomething3 End Sub
On Error Resume Next を記述した場合、エラーが発生した際は次の行から処理が継続される
この例では、DoSomething1 でエラーが発生した場合もプログラムは停止せず、DoSomething2 からプログラムが継続される。

指定したラベルにジャンプ : On Error GoTo

Sub Sample() ' エラー監視 ここから On Error GoTo myErr DoSomething ' 正常終了 Exit Sub ' エラー発生時の処理 myErr: MsgBox "エラーが発生しました。", vbExclamation End Sub
On Error GoTo を記述した場合、エラーが発生した際は指定されたラベルから処理が継続される
上の例では、エラーが発生した場合に myErr ラベルにジャンプし、そこから処理が継続(メッセージボックス表示)される。

注意が必要な点

On Error GoTo を用いてプロシージャ末尾にエラー時の処理を記述した場合、
そのままではエラーが発生しなかった場合もプロシージャ末尾の処理を実行してしまうため、ラベルの直前でプロシージャから脱出させる必要がある。

(以下、正しくない実装)
Sub Sample() ' エラー監視 ここから On Error GoTo myErr DoSomething ' ここに Exit Sub が存在しないため、エラーが発生しなかった場合も ' myErr 以下が実行されてしまう ' エラー発生時の処理 myErr: MsgBox "エラーが発生しました。", vbExclamation End Sub

Resume Next との複合

エラー時の処理に Resume Next を含めた場合、エラー発生時はラベルにジャンプ後、エラー発生個所の次行より継続される
Sub Sample() ' エラー監視 ここから ' (エラー発生時は myErr にジャンプ) On Error GoTo myErr DoSomething1 '< ① ここでエラーが発生すると ' │ ┌──────────────────┐ ' │ ↓ │ DoSomething2 '< │ ④ ここから処理が継続される │ ' │ │ ' 正常終了 │ │ Exit Sub ' │ │ ' │ │ ' エラー発生時の処理 ↓ │ myErr: '< ② ここにジャンプ │ MsgBox "エラーが発生しました。", vbExclamation ' │ ' │ Resume Next '< ③ ここからエラー発生個所の次行にジャンプ ┘ End Sub
上の例では、
① DoSomething1 でエラーが発生

② ラベル myErr にジャンプ

"エラーが発生しました。" メッセージボックス表示

③ Resume Next に遭遇

④ DoSomething2 (DoSomething1 の次行)より処理を継続
という流れとなる。

On Error を複数記述


On Error GoTo 0 を記述すると、その行以降はエラーの監視範囲外となる。
即ち、On Error GoTo 0 の直前で、それより上にある On Error ステートメントの有効範囲は終了し、次行以降に別の On Error ステートメントを記述することができる。
これにより、エラーの発生個所ごとに異なるエラー処理を実装することができる。

エラー要因の判別 (Err オブジェクト)

Sub Sample() ' エラー監視 ここから On Error GoTo myErr : Exit Sub myErr: ' エラー要因(Err.Number)に応じた処理 Select Case Err.Number Case 9 MsgBox "シート名を変更できませんでした。" & vbCrLf & Err.Description, vbExclamation Case 53 MsgBox "ファイルを開けませんでした。" & vbCrLf & Err.Description, vbExclamation Case Else MsgBox "予期せぬエラーが発生しました。", vbExclamation End Select End Sub
プログラム中でエラーが発生すると、Err オブジェクトにエラー要因に応じた値が格納される。
これにより、Err.Number (エラー番号 : 数値)および Err.Description (エラーの説明 : 文字列)から、エラー要因を確認することができる。
(要因ごとの Number および Description の値は出典元を参照。エラーが発生していない場合は Number = 0 。)

Err.Raise と Err.Clear

' エラーを発生させる f1 プロシージャ Private Sub f1(ByVal v as Integer) If v < 0 Then ' エラーをクリア Err.Clear ' エラー999を発生 Err.Raise Number:=999, Description:="something went wrong" End if End Sub ' f2 プロシージャ Private Sub f2() ' エラー監視ここから On Error Goto Have_Err ' f1 をコール(エラー発生) Call f1(-1) Have_Err: If Err.Number = 999 Then MsgBox Err.Number & vbCrLf & Err.Description Exit Sub End If End Sub
Err.Raise メソッドにより、任意の Number および Description のエラーを発生させることができる。
(これは例外機構がある言語における、例外を投げる(throw)処理に相当する。)
また、Err.Clear メソッドにより、発生していたエラーをクリアすることができる。
On Error 節でエラーを捕捉した後など、エラー情報を参照する必要が無くなった場合はクリアしておくことが望ましい。

Err.Raise メソッドの引数は 出典元 を参照。number のみが必須で、それ以外は省略可能である。